package cn.lg.soar.system.biz.modules.general.controller;

import cn.lg.soar.mvc.util.ResponseUtils;
import cn.lg.soar.system.api.constant.ModuleConst;
import cn.lg.soar.system.api.enums.ThumbnailSizeEnum;
import cn.lg.soar.system.biz.filetemplate.FileTemplateManager;
import cn.lg.soar.system.biz.util.FileAccessTokenUtils;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.S3Object;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.net.URI;

/**
 * @author luguoxiang
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
@Api(tags = "文件访问控制")
@RestController
@RequestMapping(ModuleConst.MODULE_NAME + "/file")
public class FileAccessController {

    @Autowired
    private FileTemplateManager templateManager;

    @ApiOperation("临时路径访问")
    @GetMapping("temp/{storageId}/{directory}/{fileInfo}")
    public void temp(
            @ApiParam @PathVariable int storageId,
            @ApiParam @PathVariable String directory,
            @ApiParam @PathVariable String fileInfo,
            @ApiParam @RequestParam(value = "s", required = false) ThumbnailSizeEnum size,
            HttpServletResponse response
    ) {
        String filename = FileAccessTokenUtils.parseTempUrlFileInfo(fileInfo);
        S3Object s3Object = templateManager.getTemplate(storageId).getFile(directory, filename, size);
        ObjectMetadata objectMetadata = s3Object.getObjectMetadata();
        response.setContentType(objectMetadata.getContentType() + "; charset=UTF-8");
        ResponseUtils.responseFile(objectMetadata.getContentLength(), s3Object.getObjectContent(), null);
    }

    @ApiOperation("临时路径下载")
    @GetMapping("temp/{storageId}/{directory}/{fileInfo}/{downName}")
    public void temp(
            @ApiParam @PathVariable int storageId,
            @ApiParam @PathVariable String directory,
            @ApiParam @PathVariable String fileInfo,
            @ApiParam @RequestParam(value = "s", required = false) ThumbnailSizeEnum size,
            HttpServletResponse response,
            @ApiParam @PathVariable String downName
    ) {
        String filename = FileAccessTokenUtils.parseTempUrlFileInfo(fileInfo);
        S3Object s3Object = templateManager.getTemplate(storageId).getFile(directory, filename, size);
        ObjectMetadata objectMetadata = s3Object.getObjectMetadata();
        response.setContentType(objectMetadata.getContentType() + "; charset=UTF-8");
        ResponseUtils.responseFile(objectMetadata.getContentLength(), s3Object.getObjectContent(), downName);
    }

    @ApiOperation("固定路径访问")
    @GetMapping("proxy/{storageId}/{directory}/{filename}")
    public void proxy(
            @ApiParam @PathVariable int storageId,
            @ApiParam @PathVariable String directory,
            @ApiParam @PathVariable String filename,
            @ApiParam @RequestParam(value = "s", required = false) ThumbnailSizeEnum size,
            HttpServletResponse response
    ) {
        S3Object s3Object = templateManager.getTemplate(storageId).getFile(directory, filename, size);
        ObjectMetadata objectMetadata = s3Object.getObjectMetadata();
        response.setContentType(objectMetadata.getContentType() + "; charset=UTF-8");
        ResponseUtils.responseFile(objectMetadata.getContentLength(), s3Object.getObjectContent(), null);
    }

    @ApiOperation("固定路径访问")
    @GetMapping("proxy/{storageId}/{directory}/{filename}/{downName}")
    public void proxy(
            @ApiParam @PathVariable int storageId,
            @ApiParam @PathVariable String directory,
            @ApiParam @PathVariable String filename,
            @ApiParam @RequestParam(value = "s", required = false) ThumbnailSizeEnum size,
            HttpServletResponse response,
            @ApiParam @PathVariable String downName
    ) {
        S3Object s3Object = templateManager.getTemplate(storageId).getFile(directory, filename, size);
        ObjectMetadata objectMetadata = s3Object.getObjectMetadata();
        response.setContentType(objectMetadata.getContentType() + "; charset=UTF-8");
        ResponseUtils.responseFile(objectMetadata.getContentLength(), s3Object.getObjectContent(), downName);
    }

    @ApiOperation("重定向访问")
    @GetMapping("redirect/{storageId}/{directory}/{filename}")
    public ResponseEntity<?> redirect(
            @ApiParam @PathVariable int storageId,
            @ApiParam @PathVariable String directory,
            @ApiParam @PathVariable String filename,
            @ApiParam @RequestParam(value = "s", required = false) ThumbnailSizeEnum size,
            HttpServletResponse response
    ) {
        if (size != null) {
            S3Object s3Object = templateManager.getTemplate(storageId).getFile(directory, filename, size);
            ObjectMetadata objectMetadata = s3Object.getObjectMetadata();
            response.setContentType(objectMetadata.getContentType() + "; charset=UTF-8");
            ResponseUtils.responseFile(objectMetadata.getContentLength(), s3Object.getObjectContent(), null);
        }
        // 获取临时访问路径并重定向
        String url = templateManager.getTemplate(storageId).getAccessUrl(directory, filename, 300_000);
        HttpHeaders headers = new HttpHeaders();
        headers.setLocation(URI.create(url));
        return new ResponseEntity<>(headers, HttpStatus.FOUND);
    }

    @ApiOperation("匿名访问")
    @GetMapping("anon/{storageId}/{directory}/{fileInfo}")
    public ResponseEntity<?> anon(
            @ApiParam @PathVariable int storageId,
            @ApiParam @PathVariable String directory,
            @ApiParam @PathVariable String fileInfo,
            @ApiParam @RequestParam(value = "s", required = false) ThumbnailSizeEnum size,
            @ApiParam @RequestParam(value = "r", required = false) String redirect,
            HttpServletResponse response
    ) {
        String filename = FileAccessTokenUtils.parseAnonUrlFileInfo(fileInfo);
        if ("R".equals(redirect) && size == null) {
            // 获取临时访问路径并重定向
            String url = templateManager.getTemplate(storageId).getAccessUrl(directory, filename, 300_000);
            HttpHeaders headers = new HttpHeaders();
            headers.setLocation(URI.create(url));
            return new ResponseEntity<>(headers, HttpStatus.FOUND);
        }
        S3Object s3Object = templateManager.getTemplate(storageId).getFile(directory, filename, size);
        ObjectMetadata objectMetadata = s3Object.getObjectMetadata();
        response.setContentType(objectMetadata.getContentType() + "; charset=UTF-8");
        ResponseUtils.responseFile(objectMetadata.getContentLength(), s3Object.getObjectContent(), null);
        return null;
    }

    @ApiOperation("匿名访问")
    @GetMapping("anon/{storageId}/{directory}/{fileInfo}/{downName}")
    public ResponseEntity<?> anon(
            @ApiParam @PathVariable int storageId,
            @ApiParam @PathVariable String directory,
            @ApiParam @PathVariable String fileInfo,
            @ApiParam @RequestParam(value = "s", required = false) ThumbnailSizeEnum size,
            @ApiParam @RequestParam(value = "r", required = false) String redirect,
            HttpServletResponse response,
            @ApiParam @PathVariable String downName
    ) {
        String filename = FileAccessTokenUtils.parseAnonUrlFileInfo(fileInfo);
        if ("R".equals(redirect) && size == null) {
            // 获取临时访问路径并重定向
            String url = templateManager.getTemplate(storageId).getAccessUrl(directory, filename, 300_000);
            HttpHeaders headers = new HttpHeaders();
            headers.setLocation(URI.create(url));
            return new ResponseEntity<>(headers, HttpStatus.FOUND);
        }
        S3Object s3Object = templateManager.getTemplate(storageId).getFile(directory, filename, size);
        ObjectMetadata objectMetadata = s3Object.getObjectMetadata();
        response.setContentType(objectMetadata.getContentType() + "; charset=UTF-8");
        ResponseUtils.responseFile(objectMetadata.getContentLength(), s3Object.getObjectContent(), downName);
        return null;
    }

}
